package com.twq.oo.classes

import com.twq.oo.traits.MyOrdered

/**
 * Created by tangweiqun on 2017/11/28.
 * 1、用class定义对象，并且可以有参数来构建对象
 */
class Rational(n: Int, d: Int) extends MyOrdered[Rational] {
  //4、保证构建类的数据是正确有效的，否则抛异常
  require(d != 0)
  //2、可以在class里面执行任何的代码
  println(s"Created ${n}/${d}")

  //7、分子分母约分
  private val g = gcd(n.abs, d.abs)
  val numer = n / g
  val denom = d / g

  //6、辅助构造器
  def this(n: Int) = this(n, 1)

  //5、添加一个方法
  //this是这个类的自身引用
  def add(that: Rational): Rational =
    new Rational(
      this.numer * that.denom + that.numer * this.denom,
      this.denom * that.denom
    )

  //8、定义操作符
  def +(that: Rational): Rational =
    new Rational(
      numer * that.denom + that.numer * denom,
      denom * that.denom
    )

  //9、方法重载
  def +(i: Int): Rational =
    new Rational(numer + i * denom, denom)

  def -(that: Rational): Rational =
    new Rational(
      numer * that.denom - that.numer * denom,
      denom * that.denom
    )

  def -(i: Int): Rational =
    new Rational(numer - i * denom, denom)

  def *(that: Rational): Rational =
    new Rational(numer * that.numer, denom * that.denom)

  def *(i: Int): Rational =
    new Rational(numer * i, denom)

  def /(that: Rational): Rational =
    new Rational(numer * that.denom, denom * that.numer)

  def /(i: Int): Rational =
    new Rational(numer, denom * i)

  //3、重写toString方法
  override def toString = numer + "/" + denom

  private def gcd(a: Int, b: Int): Int =
    if (b == 0) a else gcd(b, a % b)

  def compare(that: Rational) =
    (this.numer * that.denom) - (that.numer * this.denom)
}

object Rational {
  def main(args: Array[String]): Unit = {
    implicit def intToRational(x: Int) = new Rational(x)

    val r = new Rational(2, 3)

    //10、隐式转换使得Int隐式转成Rational类型
    2 * r
  }
}

